﻿
using System;
using ApplicationGenerator.Forms.WebControls;
using ApplicationGenerator.CommonModule;
using ApplicationGenerator.BusinessModule.Interfaces;
using ApplicationGenerator.Forms.Interfaces;
using ApplicationGenerator.BusinessModule.Elements;
namespace ApplicationGenerator.Forms.Actions
{
    /// <summary>
    /// Akcja powodująca zapis wartości kontrolek formularza do modelu
    /// </summary>
    [Serializable]
    public class SaveAction : ActionBase
    {
        #region Overrides
        /// <summary>
        /// Wykonuje akcję
        /// </summary>
        /// <param name="buttonControl">Kontrolka przycisku powiązanego z akcją</param>
        /// <param name="formWebControl">Kontrolka formularza</param>
        public override void Execute(ButtonControl buttonControl, FormWebControl formWebControl)
        {
            string requestType = formWebControl.Page.Request.QueryString[QuerryStringConstants.FormRequestType];
            if (requestType == QuerryStringConstants.FormRequestNew)
            {
                IModel newElement = formWebControl.Manager.CreateRootElement();
                SaveControls(formWebControl);
                formWebControl.Page.Response.Redirect(QuerryStringConstants.GenerateLoadElementFormUrl(
                    formWebControl.Page.Request.QueryString[QuerryStringConstants.FormGuid],
                    formWebControl.Manager.GetRootModelId()));
            }
            else if (requestType == QuerryStringConstants.FormRequestLoaded)
            {
                int elementId = formWebControl.ObtainElementId();
                formWebControl.Manager.LoadElement(elementId);
                SaveControls(formWebControl);
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Zapisuje wartości kontrolek do modelu
        /// </summary>
        /// <param name="formWebControl">Webowa kontrolka formularza</param>
        private void SaveControls(FormWebControl formWebControl)
        {
            BaseControl baseControl = null;
            for (int row = 0; row < formWebControl.ControlContainer.RowsCount; row++)
            {
                for (int column = 0; column < formWebControl.ControlContainer.ColumnsCount; column++)
                {
                    baseControl = formWebControl.ControlContainer.GetControl(row, column);
                    if (baseControl is ISaveControl && baseControl is BaseMappedControl)
                    {
                        IModel element = formWebControl.Manager.GetElement(((BaseMappedControl)baseControl).Path);
                        ((ISaveControl)baseControl).Save(element);
                    }
                }
            }

            formWebControl.Manager.Save();

            if (!string.IsNullOrEmpty(formWebControl.Page.Request.QueryString[QuerryStringConstants.FormParentElementId]))
            {
                int parentId = int.Parse(formWebControl.Page.Request.QueryString[QuerryStringConstants.FormParentElementId]);
                string relationFieldName = formWebControl.Page.Request.QueryString[QuerryStringConstants.FormRelationFieldName];

                IMetaModelFacade metaModelFacade = (new FacadeFactory()).CreateMetaModelFacade();
                IModelFacade modelFacade = (new FacadeFactory()).CreateModelFacade();
                IMetaField relationMetaField = formWebControl.Manager.RootMetaAdapter.MetaFieldCollection[relationFieldName];
                IModel parentModel = null;

                if (relationMetaField.MetaFieldType == MetaFieldType.List)
                {
                    string destTypeName = relationMetaField.FieldType.GetGenericArguments()[0].Name;
                    parentModel = modelFacade.LoadModel(destTypeName, parentId);
                    formWebControl.Manager.GetRootModel().AddToList(relationFieldName, parentModel);
                    formWebControl.Manager.GetRootModel().Save();
                }
                else if (relationMetaField.MetaFieldType == MetaFieldType.Relation)
                {
                    string destTypeName = relationMetaField.FieldType.Name;
                    parentModel = modelFacade.LoadModel(destTypeName, parentId);
                    formWebControl.Manager.GetRootModel().SetRelation(relationFieldName, parentModel);
                    formWebControl.Manager.GetRootModel().Save();
                }
            }
        }
        #endregion
    }
}
